#include "TcpServer.hpp"
#include "TranslateWord.hpp"
#include "Daemon.hpp"

#include <memory>
#include <cctype>
#include <algorithm>

// void Ping(int sockfd, const InetAddr &addr) //回显
// {

//     char buffer[1024];
//     int n = read(sockfd, buffer, sizeof buffer - 1);
//     if (n > 0)
//     {
//         buffer[n] = 0;
//         std::cout << addr.GetDebug() << "# " << buffer << std::endl;

//         std::string backbuffer = "server # ";
//         backbuffer += buffer;
//         write(sockfd, backbuffer.c_str(), backbuffer.size());
//     }
//     else if (n == 0) // 读完，对端关闭
//     {
//         std::cout << "client quit" << std::endl;
//     }
//     else
//     {
//         lg.LogMessage(Error, "read sockfd error, errno: %d, error: %s\n", errno, strerror(errno));
//     }
//     // close(sockfd); 不用放在这个，让Routine末尾就行
// }
void Interact(int sockfd, std::string& out, const std::string& in)
{
    char buffer[1024];
    int n = read(sockfd, buffer, sizeof buffer - 1);
    if (n > 0)
    {
        write(sockfd, in.c_str(), in.size());
    }
    else if (n == 0) // 读完，对端关闭
    {
        std::cout << "client quit" << std::endl;
    }
    else
    {
        lg.LogMessage(Error, "read sockfd error, errno: %d, error: %s\n", errno, strerror(errno));
    }   
}

void Ping(int sockfd, const InetAddr &addr) //回显
{
    lg.LogMessage(Debug, "%s select ping success, sockfd : %d\n", addr.GetDebug().c_str(), sockfd);
    std::string message; //丢弃
    Interact(sockfd, message, "pong");
    // close(sockfd); 不用放在这个，让Routine末尾就行
}

void Translate(int sockfd, const InetAddr &addr) //业务
{
    lg.LogMessage(Debug, "%s select Translate success, sockfd : %d\n", addr.GetDebug().c_str(), sockfd);
    TranslateWord trans;

    char word[64];
    int n = read(sockfd, word, sizeof word - 1);
    if(n > 0) word[n] = 0;

    std::string chinese = trans.Excute(word);

    write(sockfd, chinese.c_str(), chinese.size());

}

void Transform(int sockfd, const InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select Transform success, sockfd : %d\n", addr.GetDebug().c_str(), sockfd);
    char buffer[1024];
    int n = read(sockfd, buffer, sizeof buffer - 1);
    if(n > 0) buffer[n] = 0;
    
    std::string message = buffer;
    std::transform(message.begin(), message.end(), message.begin(), [](unsigned char c)
        {return std::toupper(c);});
    write(sockfd, message.c_str(), message.size());
}

void Default(int sockfd, const InetAddr &addr)
{
    lg.LogMessage(Debug, "%s select Default success, sockfd : %d\n", addr.GetDebug().c_str(), sockfd);
}

int main(int argc, char *argv[])
{
    uint16_t port = std::stoi(argv[1]);

    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(port);


    
    tsvr->RegisterFunc("ping", Ping);
    tsvr->RegisterFunc("translate", Translate);
    tsvr->RegisterFunc("transform", Transform);
    tsvr->RegisterFunc("default", Default);
    lg.Enable(ClassFile);
    Daemon(false, false);
    tsvr->Init();

    tsvr->Start();
}